package com.commerce.user.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.commerce.common.entity.User;

import com.commerce.common.utils.JwtUtil;
import com.commerce.common.utils.PageResult;
import com.commerce.common.exception.BusinessException;
import com.commerce.user.entity.Permission;
import com.commerce.user.entity.Role;
import com.commerce.user.entity.UserRole;
import com.commerce.user.mapper.PermissionMapper;
import com.commerce.user.mapper.RoleMapper;
import com.commerce.user.mapper.UserMapper;
import com.commerce.user.mapper.UserRoleMapper;
import com.commerce.user.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;


@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private JwtUtil jwtUtil;
    
    @Autowired
    private RoleMapper roleMapper;
    
    @Autowired
    private PermissionMapper permissionMapper;
    
    @Autowired
    private UserRoleMapper userRoleMapper;

    @Override
    public Page<User> getUserPage(Integer pageNum, Integer pageSize) {
        Page<User> page = new Page<>(pageNum, pageSize);
        return this.page(page);
    }
    
    @Override
    public Page<User> getSecureUserPage(Integer pageNum, Integer pageSize) {
        Page<User> page = new Page<>(pageNum, pageSize);
        Page<User> result = this.page(page);
        
        // 清除敏感信息
        result.getRecords().forEach(user -> {
            user.setPassword(null); // 确保密码为null，即使已有JsonIgnore注解
        });
        
        return result;
    }

    /**
     * 更新用户头像
     *
     * @param userId    用户ID
     * @param avatarUrl 头像URL
     * @return 是否更新成功
     */
    @Override
    public boolean updateAvatar(Long id, String avatarUrl) {
        User user = new User();
        user.setId(id);
        user.setIcon(avatarUrl);
        // 手动设置更新时间，确保不为空
        user.setUpdateTime(LocalDateTime.now());
        return this.updateById(user);
    }

    @Override
    public User getCurrentUser() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes == null) {
                throw new BusinessException("系统错误：无法获取请求上下文");
            }

            HttpServletRequest request = attributes.getRequest();
            if (request == null) {
                throw new BusinessException("系统错误：无法获取请求信息");
            }

            // 从请求头获取token
            String token = request.getHeader("Authorization");
            if (token == null || !token.startsWith("Bearer ")) {
                throw new BusinessException("请先登录");
            }

            // 解析token
            token = token.substring(7);
            if (!jwtUtil.validateToken(token)) {
                throw new BusinessException("登录已过期，请重新登录");
            }

            Long userId = jwtUtil.getUserIdFromToken(token);
            if (userId == null) {
                throw new BusinessException("请重新登录");
            }
            
            // 从数据库获取完整的用户信息
            User user = this.getById(userId);
            if (user == null) {
                throw new BusinessException("用户信息已失效，请重新登录");
            }

            // 设置token
            user.setToken(token);
            
            // 清除敏感信息
            user.setPassword(null);

            return user;

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException("获取用户信息失败：" + e.getMessage());
        }
    }

    @Override
    public List<User> searchUsers(String keyword) {
        if (!StringUtils.hasText(keyword)) {
            Page<User> page = new Page<>(1, 10);
            return this.page(page).getRecords();
        }
        
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(User::getUsername, keyword)
                .or().like(User::getEmail, keyword)
                .or().like(User::getPhone, keyword)
                .orderByDesc(User::getId)
                .last("LIMIT 10");
                
        List<User> users = this.list(queryWrapper);
        
        // 清除敏感信息
        users.forEach(user -> {
            user.setPassword(null);
        });
        
        return users;
    }

    @Override
    public User getUserInfo() {
        try {
            // 获取当前用户
            User user = getCurrentUser();
            if (user == null) {
                throw new BusinessException("用户未登录");
            }

            // 清除敏感信息
            user.setPassword(null);

            return user;
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException("获取用户信息失败: " + e.getMessage());
        }
    }

    @Override
    public void updateUserInfo(User user) {
        try {
            // 获取当前用户
            User currentUser = getCurrentUser();
            if (currentUser == null) {
                throw new BusinessException("用户未登录");
            }

            // 只更新允许的字段
            User updateUser = new User();
            updateUser.setId(currentUser.getId());
            updateUser.setUsername(user.getUsername());
            updateUser.setRealName(user.getRealName());
            updateUser.setIcon(user.getIcon());
            updateUser.setPhone(user.getPhone());
            updateUser.setEmail(user.getEmail());
            updateUser.setAddress(user.getAddress());
            updateUser.setBirthday(user.getBirthday());
            updateUser.setDescription(user.getDescription());
            updateUser.setUpdateTime(LocalDateTime.now());

            this.updateById(updateUser);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException("更新用户信息失败: " + e.getMessage());
        }
    }

    @Override
    public User login(String username, String password) {
        // 根据用户名查询用户
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        User user = getOne(queryWrapper);
        
        // 验证用户是否存在
        if (user == null) {
            throw new BusinessException("用户名或密码错误");
        }
        
        // 验证密码
        if (!passwordEncoder.matches(password, user.getPassword())) {
            throw new BusinessException("用户名或密码错误");
        }
        
        // 验证用户状态
        if (user.getStatus() != null && user.getStatus() != 1) {
            throw new BusinessException("账号已被禁用");
        }
        
        // 更新最后登录时间
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setLastLoginTime(LocalDateTime.now());
        updateById(updateUser);
        
        return user;
    }

    @Override
    public User getUserByUsername(String username) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        return getOne(queryWrapper);
    }

    @Override
    public User getUserByEmail(String email) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail, email);
        return getOne(queryWrapper);
    }

    @Override
    public PageResult<User> getPageList(int page, int size, String username, String email, Integer status) {
        // 创建分页对象
        Page<User> pageParam = new Page<>(page, size);
        
        // 构建查询条件
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        
        // 添加查询条件
        if (StringUtils.hasText(username)) {
            queryWrapper.like(User::getUsername, username);
        }
        
        if (StringUtils.hasText(email)) {
            queryWrapper.like(User::getEmail, email);
        }
        
        if (status != null) {
            queryWrapper.eq(User::getStatus, status);
        }
        
        // 按创建时间倒序排序
        queryWrapper.orderByDesc(User::getCreateTime);
        
        // 执行分页查询
        Page<User> userPage = this.page(pageParam, queryWrapper);
        
        // 清除敏感信息
        userPage.getRecords().forEach(user -> {
            user.setPassword(null);
        });
        
        // 封装结果
        return new PageResult<>(
            userPage.getRecords(),
            userPage.getTotal(),
            userPage.getSize(),
            userPage.getCurrent()
        );
    }

    @Override
    public List<Long> getUserPermissions(Long userId) {
        List<Permission> permissions = permissionMapper.selectByUserId(userId);
        return permissions.stream().map(Permission::getId).collect(Collectors.toList());
    }
    
    @Override
    public List<Permission> getUserPermissionList(Long userId) {
        return permissionMapper.selectByUserId(userId);
    }
    
    @Override
    public List<Role> getUserRoleList(Long userId) {
        return roleMapper.selectByUserId(userId);
    }
    
    @Override
    @Transactional
    public boolean assignUserRole(Long userId, List<Long> roleIds) {
        try {
            // 先删除原有角色
            LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserRole::getUserId, userId);
            userRoleMapper.delete(queryWrapper);
            
            // 如果角色ID列表为空，则只是清除角色
            if (roleIds == null || roleIds.isEmpty()) {
                return true;
            }
            
            // 批量插入新角色
            List<UserRole> userRoles = new ArrayList<>();
            for (Long roleId : roleIds) {
                UserRole userRole = new UserRole();
                userRole.setUserId(userId);
                userRole.setRoleId(roleId);
                userRole.setCreateTime(LocalDateTime.now());
                userRoles.add(userRole);
            }
            
            // 批量保存
            for (UserRole userRole : userRoles) {
                userRoleMapper.insert(userRole);
            }
            
            return true;
        } catch (Exception e) {
            log.error("分配用户角色失败", e);
            throw new BusinessException("分配用户角色失败: " + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public User register(User user, String password) {
        // 检查用户名是否已存在
        User existingUser = getUserByUsername(user.getUsername());
        if (existingUser != null) {
            throw new BusinessException("用户名已存在");
        }
        
        // 检查邮箱是否已存在
        if (StringUtils.hasText(user.getEmail())) {
            existingUser = getUserByEmail(user.getEmail());
            if (existingUser != null) {
                throw new BusinessException("邮箱已被使用");
            }
        }
        
        // 设置默认值
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        user.setStatus(1); // 默认启用
        user.setRole("user"); // 默认普通用户角色
        
        // 加密密码
        user.setPassword(passwordEncoder.encode(password));
        
        // 保存用户
        this.save(user);
        
        // 为新用户分配默认角色（普通用户角色，ID为2）
        List<Long> defaultRoleIds = new ArrayList<>();
        defaultRoleIds.add(2L);
        assignUserRole(user.getId(), defaultRoleIds);
        
        return user;
    }

    @Override
    public List<Role> getRoleList() {
        return roleMapper.selectList(null);
    }
    
    @Override
    public List<Permission> getPermissionList() {
        return permissionMapper.selectList(null);
    }
} 